package com.cloud.wms.ui.in.presnter;


import android.text.TextUtils;

import com.cloud.core.base.BaseRxPresenter;
import com.cloud.core.http.error.ApiException;
import com.cloud.core.utils.MessageCreator;
import com.cloud.core.utils.TimeUtils;
import com.cloud.wms.app.FineExApplication;
import com.cloud.wms.http.Params;
import com.cloud.wms.http.observer.LoadingObserver;
import com.cloud.wms.http.observer.ResponseWrapper;
import com.cloud.wms.tools.MemberFun;
import com.cloud.wms.tools.PageHelper;
import com.cloud.wms.tools.RxUtils;
import com.cloud.wms.tools.TaskHelper;
import com.cloud.wms.ui.in.contract.InInventoryContract;
import com.cloud.wms.ui.in.entity.InCommodityEntity;
import com.cloud.wms.ui.in.entity.InOrderEntity;
import com.cloud.wms.ui.main.entity.RemoteEntity;
import com.cloud.wms.ui.main.entity.TaskEntity;
import com.cloud.wms.ui.main.entity.TitleEntity;
import com.cloud.wms.ui.main.entity.UserEntity;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import javax.inject.Inject;

import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.functions.Function;

/**
 * @Author:Chen
 * @Date: 2021-01-14 15:51
 * @Description: 清点
 */
public class InInventoryPresenter extends BaseRxPresenter<InInventoryContract.View> implements InInventoryContract.Presenter {
    public static final int IN_TASK = 0x101;
    public static final int IN_ORDER = 0x102;
    public static final int IN_ORDER_DETAIL = 0x103;
    public static final int IN_CHECK_CODE = 0x104;
    public static final int IN_MARK_SUBMIT = 0x105;
    public static final int IN_BATCH_SUBMIT = 0x106;
    public static final int IN_SINGLE_SUBMIT = 0x107;
    public static final int IN_BATCH_VERIFY = 0x108;
    public static final int CHECK_COMPLETE = 0x110;

    @Inject
    public InInventoryPresenter() {

    }

    /**
     * 获取入库单列表
     *
     * @param inCode
     */
    @Override
    public void loadInOrderList(String inCode, int page) {
        Params params = Params.newInstance(Params.Type.MEMBER);
        if (!TextUtils.isEmpty(inCode))
            params.put("InCode", inCode);
        params.put("InStatus", "2");
        FineExApplication
                .component()
                .http()
                .loadInOrderList(params)
                .map(new ResponseWrapper<>())
                .map(new MemberFun<InOrderEntity>())
                .compose(mView.toLifecycle())
                .compose(RxUtils.threadSwitch())
                .subscribe(new LoadingObserver<ArrayList<TitleEntity<InOrderEntity>>>(mView.provideContext()) {
                    @Override
                    public void onSuccess(ArrayList<TitleEntity<InOrderEntity>> info) {
                        if (page == 0) {
                            mView.onSuccess(MessageCreator.createMessage(info, PageHelper.LIST_NEW_DATA));
                        } else {
                            mView.onSuccess(MessageCreator.createMessage(info, PageHelper.LIST_NEXT_DATA));
                        }
                    }

                    @Override
                    public void onError(String msg) {
                        mView.error(msg);
                        if (TextUtils.isEmpty(inCode))
                            mView.showError();
                    }
                });
    }

    /**
     * 获取可领用任务列表
     *
     * @param item
     * @param taskCode
     */
    @Override
    public void receiveInventoryTask(InOrderEntity item, String taskCode) {
        TaskHelper.receiveTask(item.getInID() + "", taskCode)
                .compose(mView.toLifecycle())
                .compose(RxUtils.threadSwitch())
                .subscribe(new LoadingObserver<TaskEntity>(mView.provideContext()) {
                    @Override
                    public void onSuccess(TaskEntity info) {
                        mView.onSuccess(MessageCreator.createMessage(info, IN_TASK));
                    }

                    @Override
                    public void onError(String msg) {
                        mView.error(msg);
                    }
                });
    }

    /**
     * 检测商品条码
     *
     * @param InID
     * @param code
     */
    @Override
    public void checkCommodityCode(String InID, String code) {
        Params params = Params.newInstance(Params.Type.MEMBER);
        params.put("BarCode", code);
        if (!TextUtils.isEmpty(InID)) {
            params.put("InID", InID);
        }

        FineExApplication
                .component()
                .http()
                .checkCommodityCode(params)
                .map(new ResponseWrapper<>())
                .flatMap((Function<InCommodityEntity, ObservableSource<InCommodityEntity>>) inCommodityEntity -> {
                    if (!TextUtils.isEmpty(InID)) {
                        if (inCommodityEntity == null) {
                            return Observable.error(new ApiException("当前入库单为查询到商品：" + code));
                        }
                        if (inCommodityEntity.getTotalAmount() <= inCommodityEntity.getInventoryAmount()) {
                            return Observable.error(new ApiException("商品：" + code + "已清点完毕！"));
                        }
                    }
                    return Observable.just(inCommodityEntity);
                })
                .compose(mView.toLifecycle())
                .compose(RxUtils.threadSwitch())
                .subscribe(new LoadingObserver<InCommodityEntity>(mView.provideContext()) {
                    @Override
                    public void onSuccess(InCommodityEntity info) {
                        mView.onSuccess(MessageCreator.createMessage(info, IN_CHECK_CODE));
                    }

                    @Override
                    public void onError(String msg) {
                        mView.error(msg);
                    }
                });
    }

    /**
     * 上架加载商品信息
     *
     * @param InID
     * @param isComplete
     */
    @Override
    public void loadInCommodityList(String InID, boolean isComplete) {
        Params params = Params.newInstance(Params.Type.MEMBER);
        //待清点：1，清单完成：2
        params.put("inType", isComplete ? 2 : 1);
        params.put("InID", InID);

        FineExApplication
                .component()
                .http()
                .loadInInventoryCommodityList(params)
                .map(new ResponseWrapper<>())
                .compose(mView.toLifecycle())
                .compose(RxUtils.threadSwitch())
                .subscribe(new LoadingObserver<ArrayList<InCommodityEntity>>(mView.provideContext()) {
                    @Override
                    public void onSuccess(ArrayList<InCommodityEntity> info) {
                        if (info == null || info.isEmpty()) {
                            mView.showEmpty();
                            mView.onSuccess(MessageCreator.createMessage(info, CHECK_COMPLETE));
                        } else {
                            mView.onSuccess(MessageCreator.createMessage(info, IN_ORDER_DETAIL));
                            mView.showContent();
                        }
                    }

                    @Override
                    public void onError(String msg) {
                        mView.error(msg);
                        mView.showError();
                    }
                });
    }

    /**
     * 有单清点--箱唛清点保存
     *
     * @param taskEntity
     * @param inOrder
     * @param commodityID
     * @param stockType
     * @param produceDate
     * @param deadlineDate
     * @param inDate
     * @param markFlag
     * @param markSize
     * @param markAmount
     * @param isPrint
     */
    @Override
    public void submitMarkInventory(TaskEntity taskEntity, InOrderEntity inOrder, long commodityID, int stockType, String produceDate, String deadlineDate,
                                    String inDate, String markFlag, String markSize, String markAmount, boolean isPrint, String beginTime) {
        Params params = Params.newInstance(Params.Type.MEMBER);
        params.put("productionDate", produceDate + " 00:00:00");
        params.put("expirationDate", deadlineDate + " 00:00:00");
        params.put("inDate", inDate + " 00:00:00");
        params.put("commodityID", commodityID);
        params.put("stockType", stockType);
        params.put("boxMarking", markFlag);
        params.put("boxStand", markSize);
        params.put("boxAmount", markAmount);
        params.put("isPrint", isPrint);
        params.put("userID", FineExApplication.component().loginCache().getUserInfo().getUserID());
        params.put("InventoryType", 3);

        Observable<Object> observable;
        if (inOrder != null) {
            params.put("workID", 0);
            params.put("InID", inOrder.getInID());
            params.put("appKey", FineExApplication.component().loginCache().getAppKey());
            params.put("beginTime", beginTime);
            params.put("completeTime", TimeUtils.getCurrentDateAndTime());
            params.put("warehouseAreaID", inOrder.getWarehouseAreaID());
        } else {
            params.put("inID", taskEntity.getMainBillID());
            params.put("inCode", taskEntity.getMainBillCode());
            params.put("JobStationID", taskEntity.getJobStationID());
            params.put("ProductCategory", taskEntity.getProductCategory());
            params.put("workID", taskEntity.getWorkID());
            params.put("appKey", taskEntity.getAppKey());
            params.put("warehouseAreaID", taskEntity.getWarehouseAreaID());
        }
        observable = FineExApplication
                .component()
                .http()
                .submitMarkInventoryTask(params)
                .map(new ResponseWrapper<>());

        observable
                .compose(mView.toLifecycle())
                .compose(RxUtils.threadSwitch())
                .subscribe(new LoadingObserver<Object>(mView.provideContext()) {
                    @Override
                    public void onSuccess(Object info) {
                        mView.onSuccess(MessageCreator.createMessage(info, IN_MARK_SUBMIT));
                    }

                    @Override
                    public void onError(String msg) {
                        mView.error(msg);
                    }
                });
    }

    /**
     * 批量清点--检测是否超收策略
     *
     * @param inOrder
     * @param entity
     */
    @Override
    public void verifySubmit(InOrderEntity inOrder, InCommodityEntity entity) {
        Params params = Params.newInstance(Params.Type.MEMBER);
//        ArrayList<HashMap<String, Object>> maps = new ArrayList<>();
//        HashMap<String, Object> map = new HashMap<>();
        params.put("productionDate", entity.getProductionDate());
        params.put("expirationDate", entity.getExpirationDate());
        params.put("inDate", entity.getInDate());
        params.put("commodityID", entity.getCommodityId());
        params.put("stockType", entity.getStockType());
        params.put("amount", entity.getAmount());
//        maps.add(map);
//        params.put("list", maps);
//        params.put("userID", FineExApplication.component().loginCache().getUserInfo().getUserID());
        if (inOrder != null) {
            params.put("InID", inOrder.getInID());
        }
        FineExApplication
                .component()
                .http()
                .verifyJudge(params)
                .map(new ResponseWrapper<>())
                .compose(mView.toLifecycle())
                .compose(RxUtils.threadSwitch())
                .subscribe(new LoadingObserver<Boolean>(mView.provideContext()) {
                    @Override
                    public void onSuccess(Boolean info) {
                        if (info)
                            mView.onSuccess(MessageCreator.createMessage(info, IN_BATCH_VERIFY));
                        else
                            onError("当前清点违反超收策略");
                    }

                    @Override
                    public void onError(String msg) {
                        mView.error(msg);
                    }
                });
    }

    /**
     * 批量清点提交
     *
     * @param taskEntity
     * @param inOrder
     * @param commodityEntity
     */
    @Override
    public void submitBatchInventory(TaskEntity taskEntity, InOrderEntity inOrder, InCommodityEntity commodityEntity, String beginTime, int what) {
        Params params = Params.newInstance(Params.Type.MEMBER);
        ArrayList<HashMap<String, Object>> maps = new ArrayList<>();

        HashMap<String, Object> map = new HashMap<>();
        map.put("productionDate", commodityEntity.getProductionDate() + " 00:00:00");
        map.put("expirationDate", commodityEntity.getExpirationDate() + " 00:00:00");
        map.put("inDate", commodityEntity.getInDate() + " 00:00:00");
        map.put("commodityID", commodityEntity.getCommodityId());
        map.put("stockType", commodityEntity.getStockType());
        map.put("amount", commodityEntity.getAmount());
        maps.add(map);

        params.put("list", maps);
        params.put("userID", FineExApplication.component().loginCache().getUserInfo().getUserID());
        params.put("InventoryType", 2);
        if (inOrder != null) {
            params.put("workID", 0);
            params.put("InID", inOrder.getInID());
            params.put("beginTime", beginTime);
            params.put("completeTime", TimeUtils.getCurrentDateAndTime());
            params.put("appKey", FineExApplication.component().loginCache().getAppKey());
            params.put("warehouseAreaID", inOrder.getWarehouseAreaID());
        } else {
            params.put("inID", taskEntity.getMainBillID());
            params.put("inCode", taskEntity.getMainBillCode());
            params.put("JobStationID", taskEntity.getJobStationID());
            params.put("ProductCategory", taskEntity.getProductCategory());
            params.put("workID", taskEntity.getWorkID());
            params.put("appKey", taskEntity.getAppKey());
            params.put("warehouseAreaID", taskEntity.getWarehouseAreaID());
        }
        FineExApplication
                .component()
                .http()
                .submitBatchAndSingleInventory(params)
                .map(new ResponseWrapper<>())
                .compose(mView.toLifecycle())
                .compose(RxUtils.threadSwitch())
                .subscribe(new LoadingObserver<Object>(mView.provideContext()) {
                    @Override
                    public void onSuccess(Object info) {
                        mView.onSuccess(MessageCreator.createMessage(info, what));
                    }

                    @Override
                    public void onError(String msg) {
                        mView.error(msg);
                    }
                });
    }

    /**
     * 逐件清点提交
     *
     * @param taskEntity
     * @param inOrder
     * @param commodityList
     */
    @Override
    public void submitSingleInventory(TaskEntity taskEntity, InOrderEntity inOrder, List<InCommodityEntity> commodityList, String beginTime) {
        Params params = Params.newInstance(Params.Type.MEMBER);
        ArrayList<HashMap<String, Object>> maps = new ArrayList<>();
        for (int i = 0; i < commodityList.size(); i++) {
            InCommodityEntity entity = commodityList.get(i);
            HashMap<String, Object> map = new HashMap<>();
            map.put("productionDate", entity.getProductionDate() + " 00:00:00");
            map.put("expirationDate", entity.getExpirationDate() + " 00:00:00");
            map.put("inDate", entity.getInDate() + " 00:00:00");
            map.put("commodityID", entity.getCommodityId());
            map.put("stockType", entity.getStockType());
            map.put("amount", entity.getAmount());
            maps.add(map);
        }
        params.put("list", maps);
        params.put("userID", FineExApplication.component().loginCache().getUserInfo().getUserID());
        params.put("InventoryType", 1);
        if (inOrder != null) {
            params.put("InID", inOrder.getInID());
            params.put("warehouseAreaID", inOrder.getWarehouseAreaID());
        }

        Observable<Object> observable;
        if (taskEntity == null) {
            params.put("workID", 0);
            params.put("beginTime", beginTime);
            params.put("completeTime", TimeUtils.getCurrentDateAndTime());
            params.put("appKey", FineExApplication.component().loginCache().getAppKey());
        } else {
            params.put("inID", taskEntity.getMainBillID());
            params.put("inCode", taskEntity.getMainBillCode());
            params.put("JobStationID", taskEntity.getJobStationID());
            params.put("ProductCategory", taskEntity.getProductCategory());
            params.put("workID", taskEntity.getWorkID());
            params.put("appKey", taskEntity.getAppKey());
            params.put("warehouseAreaID", taskEntity.getWarehouseAreaID());
        }
        observable = FineExApplication
                .component()
                .http()
                .submitBatchAndSingleInventory(params)
                .map(new ResponseWrapper<>());

        observable
                .compose(mView.toLifecycle())
                .compose(RxUtils.threadSwitch())
                .subscribe(new LoadingObserver<Object>(mView.provideContext()) {
                    @Override
                    public void onSuccess(Object info) {
                        mView.onSuccess(MessageCreator.createMessage(info, IN_SINGLE_SUBMIT));
                    }

                    @Override
                    public void onError(String msg) {
                        mView.error(msg);
                    }
                });
    }


    /**
     * 无单清点--逐件批量清点提交
     *
     * @param commodityList
     */
    @Override
    public void submitSingleNoOrderInventory(List<InCommodityEntity> commodityList, String beginTime) {
        Params params = Params.newInstance(Params.Type.MEMBER);
        ArrayList<HashMap<String, Object>> maps = new ArrayList<>();
        for (int i = 0; i < commodityList.size(); i++) {
            InCommodityEntity entity = commodityList.get(i);
            HashMap<String, Object> map = new HashMap<>();
            map.put("productionDate", entity.getProductionDate() + " 00:00:00");
            map.put("expirationDate", entity.getExpirationDate() + " 00:00:00");
            map.put("inDate", entity.getInDate() + " 00:00:00");
            map.put("commodityID", entity.getCommodityId());
            map.put("stockType", entity.getStockType());
            map.put("amount", entity.getAmount());
            maps.add(map);
        }
        params.put("list", maps);
        params.put("userID", FineExApplication.component().loginCache().getUserInfo().getUserID());
        params.put("InID", 0);
        params.put("appKey", FineExApplication.component().loginCache().getAppKey());
        FineExApplication
                .component()
                .http()
                .submitBatchAndSingleNoOrderInventory(params)
                .map(new ResponseWrapper<>())
                .compose(mView.toLifecycle())
                .compose(RxUtils.threadSwitch())
                .subscribe(new LoadingObserver<Object>(mView.provideContext()) {
                    @Override
                    public void onSuccess(Object info) {
                        mView.onSuccess(MessageCreator.createMessage(info, IN_SINGLE_SUBMIT));
                    }

                    @Override
                    public void onError(String msg) {
                        mView.error(msg);
                    }
                });
    }

    /**
     * 无单清点--箱唛保存
     *
     * @param commodityID
     * @param stockType
     * @param produceDate
     * @param deadlineDate
     * @param inDate
     * @param markFlag
     * @param markSize
     * @param markAmount
     */
    @Override
    public void submitMarkNoOrderInventory(long commodityID, int stockType, String produceDate, String deadlineDate, String inDate,
                                           String markFlag, String markSize, String markAmount) {
        Params params = Params.newInstance(Params.Type.MEMBER);
        params.put("productionDate", produceDate + " 00:00:00");
        params.put("expirationDate", deadlineDate + " 00:00:00");
        params.put("inDate", inDate + " 00:00:00");
        params.put("commodityID", commodityID);
        params.put("stockType", stockType);
        params.put("boxMarking", markFlag);
        params.put("boxStand", markSize);
        params.put("boxAmount", markAmount);
        params.put("isPrint", true);
        params.put("userID", FineExApplication.component().loginCache().getUserInfo().getUserID());
        params.put("InID", 0);
        params.put("appKey", FineExApplication.component().loginCache().getAppKey());

        FineExApplication
                .component()
                .http()
                .submitMarkNoOrderInventoryTask(params)
                .map(new ResponseWrapper<>())
                .compose(mView.toLifecycle())
                .compose(RxUtils.threadSwitch())
                .subscribe(new LoadingObserver<Object>(mView.provideContext()) {
                    @Override
                    public void onSuccess(Object info) {
                        mView.onSuccess(MessageCreator.createMessage(info, IN_MARK_SUBMIT));
                    }

                    @Override
                    public void onError(String msg) {
                        mView.error(msg);
                    }
                });
    }
}
